#include "stdafx.h"
#include "sysdebug.h"
#include "sysapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>   //mmap
#include <linux/fb.h>


#include "hi_common.h"
#include "hi_type.h"
#include "hi_comm_vb.h"
#include "hi_comm_sys.h"
#include "hi_comm_venc.h"
#include "hi_comm_vi.h"
#include "hi_comm_vo.h"
//#include "hi_comm_group.h"
#include "hi_comm_region.h"
#include "mpi_vb.h"
#include "mpi_sys.h"
#include "mpi_venc.h"
#include "mpi_vi.h"
#include "mpi_vo.h"
#include "mpi_region.h"
#include "sample_comm.h"

#include <linux/fb.h>
#include "hifb.h"
#include "loadbmp.h"
#include "hi_comm_ive.h"
#include "mpi_ive.h"

#include "hi_tde_api.h"
#include "hi_tde_type.h"
#include "hi_tde_errcode.h"


#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>

#include "OpencvIf.h"

using namespace cv;
using namespace std;

COpencvIf::COpencvIf()
{
	m_pOpencvIfPara = NULL;
}

COpencvIf::~COpencvIf()
{
	if (m_pOpencvIfPara != NULL)
	{

	}

	m_pOpencvIfPara = NULL;
}


bool COpencvIf::initOpencvIf(TOpencvIfPara* pOpencvIfPara)
{

	if (pOpencvIfPara == NULL)
		return false;

	m_pOpencvIfPara = pOpencvIfPara;

	m_VbPool = (u32)HI_MPI_VB_CreatePool(m_pOpencvIfPara->u32Width*m_pOpencvIfPara->u32Height*3, 2, NULL);
	if (m_VbPool == VB_INVALID_POOLID)
	{
		Debug(DEBUG_CRITICAL, ("####COpencvIf::initOpencvIf(): create pool  err !!!\r\n"));
		return false;
	}

	return true;
}

u32 COpencvIf::getStride(u32 u32SrcPhyAddr, u32 u32Width, eOpencvIfStrideType eOpencvStride)
{
	u32 u32Stride = 0;

	if (eOpencvStride == eOpencvIf_Stride_Byte_8)
	{
		u32Stride = (u32Width+7)/8*8;
		if ((u32Stride%8) != 0)
		{
			Debug(DEBUG_CRITICAL, ("####COpencvIf::getStride(): stride  err1 !!!\r\n"));
			return 0;
		}
	}
	else
	{
		u32Stride = (8-((u32Width+(u32SrcPhyAddr%8))%8))%8 + (u32SrcPhyAddr%8) + u32Width;
		if ((u32Stride % 8) != 0)
		{
			Debug(DEBUG_CRITICAL, ("####COpencvIf::getStride(): stride  err2 !!!\r\n"));
			return 0;
		}
	}

	return u32Stride;
}

int COpencvIf::quickCopy(CmvMat *pMatSrc, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width * pMatSrc->channels();

	stSrc.stSrcMem.u32Stride = stSrc.u32Width;
	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	s32Ret = HI_MPI_IVE_DMA(&IveHandle, &stSrc, &stDst, HI_TRUE);

	return s32Ret;
}


int COpencvIf::quickCopy(VIDEO_FRAME_INFO_S *pVideoFrame, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pVideoFrame->stVFrame.u32Height*2;
	stSrc.u32Width = pVideoFrame->stVFrame.u32Width;

	stSrc.stSrcMem.u32Stride = stSrc.u32Width;
	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pVideoFrame->stVFrame.u32PhyAddr[0];

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	s32Ret = HI_MPI_IVE_DMA(&IveHandle, &stSrc, &stDst, HI_TRUE);

	return s32Ret;
}



int COpencvIf::quickCopy(VIDEO_FRAME_INFO_S *pSrcFrame, VIDEO_FRAME_INFO_S *pDstFrame)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pSrcFrame->stVFrame.u32Height*2;
	stSrc.u32Width = pSrcFrame->stVFrame.u32Width;

	stSrc.stSrcMem.u32Stride = stSrc.u32Width;
	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pSrcFrame->stVFrame.u32PhyAddr[0];

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pDstFrame->stVFrame.u32PhyAddr[0];

	//cout << " pstVFrameInfo->u32PoolId:" << pstVFrameInfo->u32PoolId 		<< endl;

	s32Ret = HI_MPI_IVE_DMA(&IveHandle, &stSrc, &stDst, HI_TRUE);

	return s32Ret;
}


int COpencvIf::filter(CmvMat *pMatSrc, CmvMat *pMatDst, CmvMat as8Mask, u8 u8Norm)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	if (pMatSrc->channels() != 1)
	{
		Debug(DEBUG_CRITICAL, ("####COpencvIf::filter(): src channels != 1 !!!\r\n"));
		return -1;
	}

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);
	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	HI_BOOL bInstant = HI_TRUE;

	IVE_FILTER_CTRL_S stFilterCtrl;

	memcpy(stFilterCtrl.as8Mask, as8Mask.data, 9);
	stFilterCtrl.u8Norm = u8Norm;

	s32Ret = HI_MPI_IVE_FILTER(&IveHandle, &stSrc, &stDst, &stFilterCtrl, bInstant);

	return s32Ret;
}

int COpencvIf::filterVideoFrame(VIDEO_FRAME_INFO_S *pSrcVideo, VIDEO_FRAME_INFO_S *pDstVideo, CmvMat as8Mask, HI_U8 u8Norm)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pSrcVideo->stVFrame.u32Height;
	stSrc.u32Width = pSrcVideo->stVFrame.u32Width;
	stSrc.stSrcMem.u32Stride = getStride(0, pSrcVideo->stVFrame.u32Width, eOpencvIf_Stride_Byte_8);

	if (pSrcVideo->stVFrame.enPixelFormat = PIXEL_FORMAT_YUV_A422)
		stSrc.enSrcFmt = IVE_SRC_FMT_SP422;
	else
		stSrc.enSrcFmt = IVE_SRC_FMT_SP420;

	stSrc.stSrcMem.u32PhyAddr = pSrcVideo->stVFrame.u32PhyAddr[0];

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pDstVideo->stVFrame.u32PhyAddr[0];

	IVE_FILTER_CTRL_S stFilterCtrl;

	memcpy(stFilterCtrl.as8Mask, as8Mask.data, 9);
	stFilterCtrl.u8Norm = u8Norm;

	s32Ret = HI_MPI_IVE_FILTER(&IveHandle, &stSrc, &stDst, &stFilterCtrl, HI_TRUE);

	return s32Ret;
}


int COpencvIf::colorConvertoBGR(VIDEO_FRAME_INFO_S *pSrcVideo, CmvMat *pMatDst)
{
	if (pMatDst->getVirtAddr()==NULL || pMatDst->getPhyAddr()==0)
	{
		Debug(DEBUG_CRITICAL, ("####COpencvIf::ColortoBGR(): dst phy memory err!!!\r\n"));
		return -1;
	}

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_CSC_CTRL_S stCscCtrl;

	//if (pVideoFrame->stVFrame.enPixelFormat = PIXEL_FORMAT_YUV_A422)
		stSrc.enSrcFmt = IVE_SRC_FMT_SP422;

	stSrc.stSrcMem.u32PhyAddr = pSrcVideo->stVFrame.u32PhyAddr[0]; /*Data information*/
	stSrc.stSrcMem.u32Stride = getStride(0, pSrcVideo->stVFrame.u32Width, eOpencvIf_Stride_Byte_8);//pVideoSrcFrame->stVFrame.u32Stride[0];
	stSrc.u32Height = pSrcVideo->stVFrame.u32Height;   /*Data height*/
	stSrc.u32Width = pSrcVideo->stVFrame.u32Width;    /*Data width*/

	HI_VOID *pVirtDst;
	IVE_MEM_INFO_S stDst;
	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	stCscCtrl.enOutFmt = IVE_CSC_OUT_FMT_PACKAGE;	//BGR
	stCscCtrl.enCscMode = IVE_CSC_MODE_VIDEO_BT601_AND_BT656;

	HI_S32 s32Ret = HI_MPI_IVE_CSC(&IveHandle, &stSrc, &stDst, &stCscCtrl, HI_TRUE);
	if (s32Ret != HI_SUCCESS)
	{
		Debug(DEBUG_CRITICAL, ("####COpencvIf::colorConvertoBGR(): csc to bgr err!!!\r\n"));
		return -1;
	}

	pMatDst->cols = pSrcVideo->stVFrame.u32Width;
	pMatDst->rows = pSrcVideo->stVFrame.u32Height;
	pMatDst->flags = CV_8UC3;
	pMatDst->step =  pSrcVideo->stVFrame.u32Width*pMatDst->channels();
	pMatDst->dims = 2;
	return 0;
}

int COpencvIf::filterCsctoBGR(VIDEO_FRAME_INFO_S *pSrcVideo, CmvMat *pMatDst, CmvMat as8Mask, u8 u8Norm)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	if (pMatDst->getVirtAddr()==NULL || pMatDst->getPhyAddr()==0)
	{
		Debug(DEBUG_CRITICAL, ("####COpencvIf::filterCsctoBGR(): dst phy memory err!!!\r\n"));
		return -1;
	}

	stSrc.u32Height = pSrcVideo->stVFrame.u32Height;
	stSrc.u32Width = pSrcVideo->stVFrame.u32Width;
	stSrc.stSrcMem.u32Stride = getStride(0, pSrcVideo->stVFrame.u32Width, eOpencvIf_Stride_Byte_8);

	if (pSrcVideo->stVFrame.enPixelFormat = PIXEL_FORMAT_YUV_A422)
		stSrc.enSrcFmt = IVE_SRC_FMT_SP422;
	else
		stSrc.enSrcFmt = IVE_SRC_FMT_SP420;

	stSrc.stSrcMem.u32PhyAddr = pSrcVideo->stVFrame.u32PhyAddr[0];

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	HI_BOOL bInstant = HI_TRUE;

	IVE_FILTER_AND_CSC_CTRL_S stFltCscCtrl;

	memcpy(stFltCscCtrl.as8Mask, as8Mask.data, 9);
	stFltCscCtrl.u8Norm = u8Norm;
	stFltCscCtrl.enOutFmt = IVE_CSC_OUT_FMT_PACKAGE;	//BGR
	stFltCscCtrl.enCscMode = IVE_CSC_MODE_VIDEO_BT601_AND_BT656;

	s32Ret = HI_MPI_IVE_FILTER_AND_CSC(&IveHandle, &stSrc, &stDst, &stFltCscCtrl, bInstant);

	return s32Ret;
}




int COpencvIf::canny(CmvMat *pMatSrc, CmvMat *pMatDst, CmvMat as8Mask)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;
	//IVE_MEM_INFO_S stDstAng;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	IVE_CANNY_CTRL_S stCannyCtrl;

	stCannyCtrl.enOutFmt = IVE_CANNY_OUT_FMT_ONLY_MAG;
	memcpy(stCannyCtrl.as8Mask, as8Mask.data, 9);


	s32Ret = HI_MPI_IVE_CANNY(&IveHandle, &stSrc, &stDst, NULL, &stCannyCtrl, HI_TRUE);


	return s32Ret;
}



int COpencvIf::dilate(CmvMat *pMatSrc, CmvMat *pMatDst, CmvMat au8Mask)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;
	//IVE_MEM_INFO_S stDstAng;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	IVE_DILATE_CTRL_S stDilateCtrl;

	memcpy(stDilateCtrl.au8Mask, au8Mask.data, 9);

	s32Ret = HI_MPI_IVE_DILATE(&IveHandle, &stSrc, &stDst, &stDilateCtrl, HI_TRUE);

	return s32Ret;
}

int COpencvIf::erode(CmvMat *pMatSrc, CmvMat *pMatDst, CmvMat au8Mask)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;
	//IVE_MEM_INFO_S stDstAng;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	IVE_ERODE_CTRL_S stErodeCtrl;

	memcpy(stErodeCtrl.au8Mask, au8Mask.data, 9);

	s32Ret = HI_MPI_IVE_ERODE(&IveHandle, &stSrc, &stDst, &stErodeCtrl, HI_TRUE);

	return s32Ret;
}

int COpencvIf::thresh(CmvMat *pMatSrc, CmvMat *pMatDst, u32 u32Thresh, u32 u32MinVal, u32 u32MaxVal)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	IVE_THRESH_CTRL_S stThreshCtrl;
	stThreshCtrl.enOutFmt = IVE_THRESH_OUT_FMT_BINARY;
	stThreshCtrl.u32Thresh = u32Thresh;
	stThreshCtrl.u32MinVal = 0;
	stThreshCtrl.u32MaxVal = 255;

	s32Ret = HI_MPI_IVE_THRESH(&IveHandle, &stSrc, &stDst, &stThreshCtrl, HI_TRUE);

	return s32Ret;
}


int COpencvIf::andIamge(CmvMat *pMatSrc1, CmvMat *pMatSrc2, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc1;
	IVE_SRC_INFO_S stSrc2;
	IVE_MEM_INFO_S stDst;

	stSrc1.u32Height = pMatSrc1->size().height;
	stSrc1.u32Width = pMatSrc1->size().width;
	stSrc1.stSrcMem.u32Stride = getStride(0, stSrc1.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc1.enSrcFmt = IVE_SRC_FMT_SINGLE;
	stSrc1.stSrcMem.u32PhyAddr = pMatSrc2->getPhyAddr();

	stSrc2.u32Height = pMatSrc2->size().height;
	stSrc2.u32Width = pMatSrc2->size().width;
	stSrc2.stSrcMem.u32Stride = getStride(0, stSrc1.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc2.enSrcFmt = IVE_SRC_FMT_SINGLE;
	stSrc2.stSrcMem.u32PhyAddr = pMatSrc2->getPhyAddr();

	stDst.u32Stride = stSrc1.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	s32Ret = HI_MPI_IVE_AND(&IveHandle, &stSrc1, &stSrc2, &stDst, HI_TRUE);

	return s32Ret;
}


int COpencvIf::subIamge(CmvMat *pMatSrc1, CmvMat *pMatSrc2, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc1;
	IVE_SRC_INFO_S stSrc2;
	IVE_MEM_INFO_S stDst;

	stSrc1.u32Height = pMatSrc1->size().height;
	stSrc1.u32Width = pMatSrc1->size().width;
	stSrc1.stSrcMem.u32Stride = getStride(0, stSrc1.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc1.enSrcFmt = IVE_SRC_FMT_SINGLE;
	stSrc1.stSrcMem.u32PhyAddr = pMatSrc2->getPhyAddr();

	stSrc2.u32Height = pMatSrc2->size().height;
	stSrc2.u32Width = pMatSrc2->size().width;
	stSrc2.stSrcMem.u32Stride = getStride(0, stSrc1.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc2.enSrcFmt = IVE_SRC_FMT_SINGLE;
	stSrc2.stSrcMem.u32PhyAddr = pMatSrc2->getPhyAddr();

	stDst.u32Stride = stSrc1.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	IVE_SUB_OUT_FMT_E enOutFmt = IVE_SUB_OUT_FMT_ABS;

	s32Ret = HI_MPI_IVE_SUB(&IveHandle, &stSrc1, &stSrc2, &stDst, enOutFmt, HI_TRUE);

	return s32Ret;
}


int COpencvIf::orIamge(CmvMat *pMatSrc1, CmvMat *pMatSrc2, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc1;
	IVE_SRC_INFO_S stSrc2;
	IVE_MEM_INFO_S stDst;

	stSrc1.u32Height = pMatSrc1->size().height;
	stSrc1.u32Width = pMatSrc1->size().width;
	stSrc1.stSrcMem.u32Stride = getStride(0, stSrc1.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc1.enSrcFmt = IVE_SRC_FMT_SINGLE;
	stSrc1.stSrcMem.u32PhyAddr = pMatSrc2->getPhyAddr();

	stSrc2.u32Height = pMatSrc2->size().height;
	stSrc2.u32Width = pMatSrc2->size().width;
	stSrc2.stSrcMem.u32Stride = getStride(0, stSrc1.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc2.enSrcFmt = IVE_SRC_FMT_SINGLE;
	stSrc2.stSrcMem.u32PhyAddr = pMatSrc2->getPhyAddr();

	stDst.u32Stride = stSrc1.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	s32Ret = HI_MPI_IVE_OR(&IveHandle, &stSrc1, &stSrc2, &stDst, HI_TRUE);

	return s32Ret;
}

int COpencvIf::integ(CmvMat *pMatSrc, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	s32Ret = HI_MPI_IVE_INTEG(&IveHandle, &stSrc, &stDst, HI_TRUE);

	return s32Ret;
}

int COpencvIf::hist(CmvMat *pMatSrc, CmvMat *pMatDst)
{
	HI_S32 s32Ret = HI_SUCCESS;

	IVE_HANDLE IveHandle;
	IVE_SRC_INFO_S stSrc;
	IVE_MEM_INFO_S stDst;

	stSrc.u32Height = pMatSrc->size().height;
	stSrc.u32Width = pMatSrc->size().width;
	stSrc.stSrcMem.u32Stride = getStride(0, stSrc.u32Width, eOpencvIf_Stride_Byte_8);

	stSrc.enSrcFmt = IVE_SRC_FMT_SINGLE;

	stSrc.stSrcMem.u32PhyAddr = pMatSrc->getPhyAddr();

	stDst.u32Stride = stSrc.stSrcMem.u32Stride;
	stDst.u32PhyAddr = pMatDst->getPhyAddr();

	s32Ret = HI_MPI_IVE_HIST(&IveHandle, &stSrc, &stDst, HI_TRUE);

	return s32Ret;
}


//Mat view

int COpencvIf::videoHiFrameToMat(VIDEO_FRAME_INFO_S *pVideoFrame, CmvMat *pMatDst)
{
	//conver BGR
	//return colorConvertoBGR(pVideoFrame, pView);
	pMatDst->cols = pVideoFrame->stVFrame.u32Width;
	pMatDst->rows = pVideoFrame->stVFrame.u32Height;
	//pMatDst->flags = CV_
	pMatDst->step =  pVideoFrame->stVFrame.u32Width*pMatDst->channels();
	pMatDst->dims = 2;

	return quickCopy(pVideoFrame, pMatDst);
}


int COpencvIf::videoMatToHiFrame(CmvMat *pView, VIDEO_FRAME_INFO_S *pstVFrameInfo, VO_DEV VoDev, VO_CHN VoChn)
{
	u32 u32LStride;
	u32 u32CStride;
	u32 u32LumaSize;
	u32 u32ChrmSize;
	u32 u32Size;
	VB_BLK VbBlk;
	u32 u32PhyAddr;
	u8 *pVirAddr;

	u32 u32Stride = getStride(0, pView->cols, eOpencvIf_Stride_Byte_8);
	u32LStride = u32Stride;
	u32CStride = u32Stride;

	u32LumaSize = (u32LStride * pView->rows);
	u32ChrmSize = (u32CStride * pView->rows) >> 2;/* YUV 420 */
	//u32ChrmSize = (u32CStride * pView->size().height) >> 1;/* YUV 422 */
	//u32ChrmSize = (u32CStride * pView->size().height);
	u32Size = u32LumaSize + (u32ChrmSize << 1);

	/* alloc video buffer block ---------------------------------------------------------- */
	VbBlk = HI_MPI_VB_GetBlock(m_VbPool, u32Size, NULL);
	if (VB_INVALID_HANDLE == VbBlk)
	{
		SAMPLE_PRT("HI_MPI_VB_GetBlock err! size:%d\n", u32Size);
		return -1;
	}

	u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(VbBlk);
	if (0 == u32PhyAddr)
	{
		return -1;
	}

	pVirAddr = (HI_U8 *) HI_MPI_SYS_Mmap(u32PhyAddr, u32Size);
	if (NULL == pVirAddr)
	{
		return -1;
	}

	pstVFrameInfo->u32PoolId = HI_MPI_VB_Handle2PoolId(VbBlk);
	if (VB_INVALID_POOLID == pstVFrameInfo->u32PoolId)
	{
		SAMPLE_PRT("pool id :%d, phyAddr:%x,virAddr:%x\n", pstVFrameInfo->u32PoolId,
		u32PhyAddr, (int )pVirAddr);
		return -1;
	}

	pstVFrameInfo->stVFrame.u32PhyAddr[0] = u32PhyAddr;
	pstVFrameInfo->stVFrame.u32PhyAddr[1] =
		pstVFrameInfo->stVFrame.u32PhyAddr[0] + u32LumaSize;
	pstVFrameInfo->stVFrame.u32PhyAddr[2] =
		pstVFrameInfo->stVFrame.u32PhyAddr[1] + u32ChrmSize;

	pstVFrameInfo->stVFrame.pVirAddr[0] = pVirAddr;
	pstVFrameInfo->stVFrame.pVirAddr[1] = pstVFrameInfo->stVFrame.pVirAddr[0]
		+ u32LumaSize;
	pstVFrameInfo->stVFrame.pVirAddr[2] = pstVFrameInfo->stVFrame.pVirAddr[1]
		+ u32ChrmSize;

	pstVFrameInfo->stVFrame.u32Width = pView->size().width;
	pstVFrameInfo->stVFrame.u32Height = pView->size().height;
	pstVFrameInfo->stVFrame.u32Stride[0] = u32LStride;
	pstVFrameInfo->stVFrame.u32Stride[1] = u32CStride;
	pstVFrameInfo->stVFrame.u32Stride[2] = u32CStride;
	pstVFrameInfo->stVFrame.enPixelFormat = SAMPLE_PIXEL_FORMAT;
	pstVFrameInfo->stVFrame.u32Field = VIDEO_FIELD_INTERLACED;/* Intelaced D1,otherwise VIDEO_FIELD_FRAME */
/*
	// read Y U V data from file to the addr ----------------------------------------------
	SAMPLE_COMM_VI_ReadFrame(pYUVFile, pstVFrameInfo->stVFrame.pVirAddr[0],
		pstVFrameInfo->stVFrame.pVirAddr[1],
		pstVFrameInfo->stVFrame.pVirAddr[2], pstVFrameInfo->stVFrame.u32Width,
		pstVFrameInfo->stVFrame.u32Height, pstVFrameInfo->stVFrame.u32Stride[0],
		pstVFrameInfo->stVFrame.u32Stride[1] >> 1);
*/
	// convert planar YUV420 to sem-planar YUV420 -----------------------------------------
	SAMPLE_COMM_VI_PlanToSemi((u8 *)pstVFrameInfo->stVFrame.pVirAddr[0],
		pstVFrameInfo->stVFrame.u32Stride[0],
		(u8 *)pstVFrameInfo->stVFrame.pVirAddr[1],
		pstVFrameInfo->stVFrame.u32Stride[1],
		(u8 *)pstVFrameInfo->stVFrame.pVirAddr[2],
		pstVFrameInfo->stVFrame.u32Stride[1], pstVFrameInfo->stVFrame.u32Width,
		pstVFrameInfo->stVFrame.u32Height);

	HI_MPI_SYS_Munmap(pVirAddr, u32Size);

	HI_MPI_VO_SendFrame(VoDev, VoChn, pstVFrameInfo);
	HI_MPI_VB_ReleaseBlock(VbBlk);

	return 0;
}


int COpencvIf::videoToHiFrame(VIDEO_FRAME_INFO_S *pstSrcVFrameInfo, VIDEO_FRAME_INFO_S *pstVFrameInfo, VO_DEV VoDev, VO_CHN VoChn)
{
	u32 u32LStride;
	u32 u32CStride;
	u32 u32LumaSize;
	u32 u32ChrmSize;
	u32 u32Size;
	VB_BLK VbBlk;
	u32 u32PhyAddr;
	u8 *pVirAddr;


	memcpy((u8 *)pstVFrameInfo, (u8 *)pstSrcVFrameInfo, sizeof(VIDEO_FRAME_INFO_S));

	cout << " memcpy->enPixelFormat:"	<< pstVFrameInfo->stVFrame.enPixelFormat << endl;
	cout << " memcpy->u32Width:" << pstVFrameInfo->stVFrame.u32Width		<< endl;
	cout << " memcpy->u32Height:" << pstVFrameInfo->stVFrame.u32Height		<< endl;
	cout << " memcpy->u32PhyAddr:"		<< pstVFrameInfo->stVFrame.u32PhyAddr[0] << endl;
	cout << " memcpy->u32PhyAddr:"		<< pstVFrameInfo->stVFrame.u32PhyAddr[1] << endl;
	cout << " memcpy->u32PhyAddr:"		<< pstVFrameInfo->stVFrame.u32PhyAddr[2] << endl;
	cout << " memcpy->u32VirAddr:"		<< pstVFrameInfo->stVFrame.pVirAddr[0] << endl;
	cout << " memcpy->u32VirAddr:"		<< pstVFrameInfo->stVFrame.pVirAddr[1] << endl;
	cout << " memcpy->u32VirAddr:"		<< pstVFrameInfo->stVFrame.pVirAddr[2] << endl;

	cout << " memcpy->u32Stride:" << pstVFrameInfo->stVFrame.u32Stride[0]		<< endl;
	cout << " memcpy->u32Stride:" << pstVFrameInfo->stVFrame.u32Stride[1]		<< endl;
	cout << " memcpy->u32Stride:" << pstVFrameInfo->stVFrame.u32Stride[2]		<< endl;
	cout << " memcpy->u32PoolId:" << pstVFrameInfo->u32PoolId 		<< endl;

	cout << " memcpy->u32Field:" << pstVFrameInfo->stVFrame.u32Field 		<< endl;
	cout << " memcpy->u16OffsetTop:" << pstVFrameInfo->stVFrame.u16OffsetTop 		<< endl;
	cout << " memcpy->u16OffsetBottom:" << pstVFrameInfo->stVFrame.u16OffsetBottom 		<< endl;
	cout << " memcpy->u16OffsetLeft:" << pstVFrameInfo->stVFrame.u16OffsetLeft 		<< endl;
	cout << " memcpy->u16OffsetRight:" << pstVFrameInfo->stVFrame.u16OffsetRight 		<< endl;
	cout << " memcpy->u32Field:" << pstVFrameInfo->stVFrame.u32Field 		<< endl;

	cout << " memcpy->u64pts:" << pstVFrameInfo->stVFrame.u64pts 		<< endl;
		cout << " memcpy->u32TimeRef:" << pstVFrameInfo->stVFrame.u32TimeRef 		<< endl;
		cout << " memcpy->u32PrivateData:" << pstVFrameInfo->stVFrame.u32PrivateData 		<< endl;

	u32 u32Stride = getStride(0, pstSrcVFrameInfo->stVFrame.u32Width, eOpencvIf_Stride_Byte_8);
	u32LStride = u32Stride;
	u32CStride = u32Stride;

	u32LumaSize = (u32LStride * pstSrcVFrameInfo->stVFrame.u32Height);
	u32ChrmSize = (u32CStride * pstSrcVFrameInfo->stVFrame.u32Height) >> 2;/* YUV 420 */
	//u32ChrmSize = (u32CStride * pstSrcVFrameInfo->stVFrame.u32Height>>1);/* YUV 422 */
	//u32ChrmSize = (u32CStride * pView->size().height);
	u32Size = u32LumaSize + (u32ChrmSize << 1);

	/* alloc video buffer block ---------------------------------------------------------- */
	VbBlk = HI_MPI_VB_GetBlock(m_VbPool, u32Size, NULL);
	if (VB_INVALID_HANDLE == VbBlk)
	{
		SAMPLE_PRT("HI_MPI_VB_GetBlock err! size:%d\n", u32Size);
		return -1;
	}

	u32PhyAddr = HI_MPI_VB_Handle2PhysAddr(VbBlk);
	if (0 == u32PhyAddr)
	{
		return -1;
	}



	pVirAddr = (HI_U8 *) HI_MPI_SYS_Mmap(u32PhyAddr, u32Size);
	if (NULL == pVirAddr)
	{
		return -1;
	}
	cout << " new mmz ->u32Size :" << u32Size 		<< endl;
	cout << " new mmz ->pVirAddr :" << (int )pVirAddr 		<< endl;

	pstVFrameInfo->u32PoolId = HI_MPI_VB_Handle2PoolId(VbBlk);
	if (VB_INVALID_POOLID == pstVFrameInfo->u32PoolId)
	{
		SAMPLE_PRT("pool id :%d, phyAddr:%x,virAddr:%x\n", pstVFrameInfo->u32PoolId,
		u32PhyAddr, (int )pVirAddr);
		return -1;
	}

	pstVFrameInfo->stVFrame.u32PhyAddr[0] = u32PhyAddr;
	pstVFrameInfo->stVFrame.u32PhyAddr[1] =		pstVFrameInfo->stVFrame.u32PhyAddr[0] + u32LumaSize;
	pstVFrameInfo->stVFrame.u32PhyAddr[2] =		0;//pstVFrameInfo->stVFrame.u32PhyAddr[1] + u32ChrmSize;

	pstVFrameInfo->stVFrame.pVirAddr[0] = pVirAddr;
	pstVFrameInfo->stVFrame.pVirAddr[1] = pstVFrameInfo->stVFrame.pVirAddr[0]	+ u32LumaSize;
	pstVFrameInfo->stVFrame.pVirAddr[2] = 0;//pstVFrameInfo->stVFrame.pVirAddr[1]	+ u32ChrmSize;

	pstVFrameInfo->stVFrame.u32Width = pstSrcVFrameInfo->stVFrame.u32Width;
	pstVFrameInfo->stVFrame.u32Height = pstSrcVFrameInfo->stVFrame.u32Height;
	pstVFrameInfo->stVFrame.u32Stride[0] = u32LStride;
	pstVFrameInfo->stVFrame.u32Stride[1] = u32CStride;
	pstVFrameInfo->stVFrame.u32Stride[2] = 0;
	pstVFrameInfo->stVFrame.enPixelFormat = PIXEL_FORMAT_YUV_SEMIPLANAR_420;//SAMPLE_PIXEL_FORMAT
	pstVFrameInfo->stVFrame.u32Field = VIDEO_FIELD_FRAME;/* Intelaced D1,otherwise VIDEO_FIELD_FRAME */


	//quickCopy(pstSrcVFrameInfo, pstVFrameInfo);

/*
	// read Y U V data from file to the addr ----------------------------------------------
	SAMPLE_COMM_VI_ReadFrame(pYUVFile, pstVFrameInfo->stVFrame.pVirAddr[0],
		pstVFrameInfo->stVFrame.pVirAddr[1],
		pstVFrameInfo->stVFrame.pVirAddr[2], pstVFrameInfo->stVFrame.u32Width,
		pstVFrameInfo->stVFrame.u32Height, pstVFrameInfo->stVFrame.u32Stride[0],
		pstVFrameInfo->stVFrame.u32Stride[1] >> 1);
*/
	// convert planar YUV420 to sem-planar YUV420 -----------------------------------------
	/*
	SAMPLE_COMM_VI_PlanToSemi((u8 *)pstVFrameInfo->stVFrame.pVirAddr[0],
		pstVFrameInfo->stVFrame.u32Stride[0],
		(u8 *)pstVFrameInfo->stVFrame.pVirAddr[1],
		pstVFrameInfo->stVFrame.u32Stride[1],
		(u8 *)pstVFrameInfo->stVFrame.pVirAddr[2],
		pstVFrameInfo->stVFrame.u32Stride[1], pstVFrameInfo->stVFrame.u32Width,
		pstVFrameInfo->stVFrame.u32Height);
*/



	cout << " pstVFrameInfo->enPixelFormat:" << pstVFrameInfo->stVFrame.enPixelFormat << endl;
			cout << " pstVFrameInfo->u32Width:" <<  pstVFrameInfo->stVFrame.u32Width << endl;
			cout << " pstVFrameInfo->u32Height:" <<  pstVFrameInfo->stVFrame.u32Height << endl;
			cout << " pstVFrameInfo->u32PhyAddr:" << pstVFrameInfo->stVFrame.u32PhyAddr[0] << endl;
			cout << " pstVFrameInfo->u32PhyAddr:" <<  pstVFrameInfo->stVFrame.u32PhyAddr[1] << endl;
			cout << " pstVFrameInfo->u32PhyAddr:" <<  pstVFrameInfo->stVFrame.u32PhyAddr[2] << endl;
			cout << " pstVFrameInfo->u32VirAddr:"		<< pstVFrameInfo->stVFrame.pVirAddr[0] << endl;
				cout << " pstVFrameInfo->u32VirAddr:"		<< pstVFrameInfo->stVFrame.pVirAddr[1] << endl;
				cout << " pstVFrameInfo->u32VirAddr:"		<< pstVFrameInfo->stVFrame.pVirAddr[2] << endl;
			cout << " pstVFrameInfo->u32Stride:" <<  pstVFrameInfo->stVFrame.u32Stride[0] << endl;
			cout << " pstVFrameInfo->u32Stride:" <<  pstVFrameInfo->stVFrame.u32Stride[1] << endl;
			cout << " pstVFrameInfo->u32Stride:" <<  pstVFrameInfo->stVFrame.u32Stride[2] << endl;
			cout << " pstVFrameInfo->u32PoolId:" << pstVFrameInfo->u32PoolId 		<< endl;

			cout << " pstVFrameInfo->u32Field:" << pstVFrameInfo->stVFrame.u32Field 		<< endl;
				cout << " pstVFrameInfo->u16OffsetTop:" << pstVFrameInfo->stVFrame.u16OffsetTop 		<< endl;
				cout << " pstVFrameInfo->u16OffsetBottom:" << pstVFrameInfo->stVFrame.u16OffsetBottom 		<< endl;
				cout << " pstVFrameInfo->u16OffsetLeft:" << pstVFrameInfo->stVFrame.u16OffsetLeft 		<< endl;
				cout << " pstVFrameInfo->u16OffsetRight:" << pstVFrameInfo->stVFrame.u16OffsetRight 		<< endl;
				cout << " pstVFrameInfo->u32Field:" << pstVFrameInfo->stVFrame.u32Field 		<< endl;

				cout << " pstVFrameInfo->u64pts:" << pstVFrameInfo->stVFrame.u64pts 		<< endl;
					cout << " pstVFrameInfo->u32TimeRef:" << pstVFrameInfo->stVFrame.u32TimeRef 		<< endl;
					cout << " pstVFrameInfo->u32PrivateData:" << pstVFrameInfo->stVFrame.u32PrivateData 		<< endl;

	//memcpy((u8 *)pVirAddr, (u8 *)pstSrcVFrameInfo->stVFrame.pVirAddr[0], u32Size);
	//memcpy((u8 *)pstVFrameInfo->stVFrame.pVirAddr[1], (u8 *)pstSrcVFrameInfo->stVFrame.pVirAddr[1], pstSrcVFrameInfo->stVFrame.u32Height*pstSrcVFrameInfo->stVFrame.u32Stride[1]>>1);

	HI_MPI_VO_SendFrame(VoDev, VoChn, pstVFrameInfo);

	HI_MPI_SYS_Munmap(pVirAddr, u32Size);
	HI_MPI_VB_ReleaseBlock(VbBlk);

	return 0;
}

int COpencvIf::createIplImage(IplImage &image, Size imageSize, char *pVirt)
{
	image.nSize = imageSize.width * imageSize.height;
	image.ID = 0;
	image.nChannels = 3;
	image.depth = IPL_DEPTH_8U;
	image.dataOrder = IPL_DATA_ORDER_PIXEL;
	image.origin = IPL_ORIGIN_TL;

	image.width = imageSize.width;
	image.height = imageSize.height;
	image.roi = NULL;
	image.maskROI = NULL;
	image.imageId = NULL;
	image.tileInfo = NULL;

	image.imageSize = image.width * image.height;
	image.imageData = (char *)pVirt;

	image.widthStep = image.width*image.nChannels;
	image.imageDataOrigin = NULL;

	return 0;
}


